package org.dctmcommons.impl;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.dctmcommons.IParamCheck;
import org.dctmcommons.IQueryHelper;
import org.dctmcommons.ITypedObjectCallback;
import org.dctmcommons.IVirtualDocHelper;

import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfTypedObject;
import com.documentum.fc.common.DfException;

import static com.documentum.fc.common.DfDocbaseConstants.*;

/**
 * Default implementation of {link IVirtualDocHelper}.
 * @author Mark Davidson
 */
public class VirtualDocHelper implements IVirtualDocHelper {

	/**
	 * Private constructor.
	 */
	private VirtualDocHelper() {}

	/**
	 * Factory method.
	 * @return A new doc helper instance
	 */
	public static IVirtualDocHelper getInstance() {
		return new VirtualDocHelper();
	}
	
	/** DQL template to identify children of a virtual doc. */
	private static final String DQL_GET_CHILD_DOC_IDS =
		"select " + R_OBJECT_ID +
		" from " + DM_SYSOBJECT +
		" in document id(''{0}'') {1}" +
		" with any " + R_VERSION_LABEL + " = ''CURRENT''";
	
	/** The parameter check instance. */
	private static final IParamCheck paramCheck = ParamCheck.getInstance();

	/** The query helper instance. */
	private static final IQueryHelper queryHelper = QueryHelper.getInstance();
	
	/*
	 * (non-Javadoc)
	 * @see org.dctmcommons.IVirtualDocHelper#getChildDocumentIds(com.documentum.fc.client.IDfSession, java.lang.String, boolean, boolean)
	 */
	@Override
	public String[] getChildDocumentIds(final IDfSession session,
										final String objectId,
										final boolean includeRoot,
										final boolean recursive)
		throws DfException {
		
		paramCheck.checkObject(session, "session");
		paramCheck.checkString(objectId, "objectId");
		
		final String descend = recursive ? "descend" : "";
		final String dql = MessageFormat.format(DQL_GET_CHILD_DOC_IDS,
												objectId,
												descend);
		final List<String> list = new ArrayList<String>();
		
		queryHelper.query(session,
						  dql,
						  IDfQuery.DF_READ_QUERY,
						  new ITypedObjectCallback() {
			@Override
			public boolean read(final IDfTypedObject typedObject)
				throws DfException {
				final String childId = typedObject.getString(R_OBJECT_ID);
				if (includeRoot ||
					(!includeRoot && !childId.equals(objectId))) {
					list.add(childId);
				}
				return true;
			}
		});
		
		if (list.size() > 0) {
			return list.toArray(new String[] {});
		} else {
			return null;
		}
	}

}
